package com.googlecode.perfectable.visuable.configuration;

import javax.annotation.Nullable;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.googlecode.perfectable.introspection.Classes;

public class ConfigurationListener implements ServletContextListener {

	private static final String CONFIGURATOR_PARAMETER = "configuratorInstance";
	private static final String CONFIGURATOR_CLASS_PARAMETER = "configuratorClass";

	@Override
	public void contextInitialized(@Nullable ServletContextEvent sce) {
		if(sce == null) {
			throw new IllegalArgumentException();
		}
		ServletContext context = sce.getServletContext();
		if(context.getAttribute(CONFIGURATOR_PARAMETER) != null) {
			return;
		}
		final String configuratorClass = context.getInitParameter(CONFIGURATOR_CLASS_PARAMETER);
		Configurator configurator = createConfigurator(configuratorClass);
		context.setAttribute(CONFIGURATOR_PARAMETER, configurator);
	}

	@Override
	public void contextDestroyed(@Nullable ServletContextEvent sce) {
		if(sce == null) {
			throw new IllegalArgumentException();
		}
	}

	private static Configurator createConfigurator(@Nullable String configuratorClass) {
		if(configuratorClass == null) {
			return new StandardConfigurator();
		}
		return Classes.instantiate(configuratorClass, Configurator.class);
	}

	public static Configurator extractConfigurator(ServletContext servletContext) {
		final Configurator configurator = (Configurator) servletContext.getAttribute(CONFIGURATOR_PARAMETER);
		if(configurator == null) {
			throw new IllegalStateException("Configurator was not created for servlet context. Is "
					+ ConfigurationListener.class.getName() + " added as listener?");
		}
		return configurator;
	}

}
